package heap

import (
	C "gitee.com/ljfirst/algo-go-sdk/common/constant"
	"reflect"
)

/**
 * @author ljfirst
 * @version V1.0
 * @date 2023/7/26 00:15
 * @author-Email ljfirst@mail.ustc.edu.cn
 * @blogURL https://blog.csdn.net/ljfirst
 * @description 滑动窗口的最大值
 **/
type MaxSlidingWindowByPQ struct {
	slidingWindow []int
}

func (m *MaxSlidingWindowByPQ) Method(array []int, k int) []int {
	if len(array) < 0 {
		return nil
	}
	m.slidingWindow = make([]int, 0)
	/*PQ := NewPriorityQueue(
		C.WithLimitSize(k),
		C.WithChange(m.change),
		C.WithGT(m.gt),
		C.WithCompare(m.comp))
	for i := 0; i < len(array); i++ {
		if !PQ.Empty() && i-PQ.Peak().([]int)[1] >= k {
			PQ.Poll()
		}
		PQ.Offer([]int{array[i], i})
		if !PQ.Empty() && i >= k-1 {
			m.slidingWindow = append(m.slidingWindow, PQ.Peak().([]int)[0])
		}
	}*/
	return m.slidingWindow
}

func (m *MaxSlidingWindowByPQ) gt(array interface{}, indexA, indexB int) bool {
	value := reflect.ValueOf(array)
	if value.Kind() != reflect.Array && value.Kind() != reflect.Slice {
		return false
	}
	if value.Len() <= indexA || value.Len() <= indexB {
		return false
	}
	arr, ok := array.([]interface{})
	if !ok {
		return false
	}
	a, ok := arr[indexA].([]int)
	if !ok {
		return false
	}
	b, ok := arr[indexB].([]int)
	if !ok {
		return false
	}
	return a[0] > b[0]
}

func (m *MaxSlidingWindowByPQ) change(array interface{}, indexA, indexB int) {
	value := reflect.ValueOf(array)
	if value.Kind() != reflect.Array && value.Kind() != reflect.Slice {
		return
	}
	if value.Len() <= indexA || value.Len() <= indexB {
		return
	}
	arr, ok := array.([]interface{})
	if !ok {
		return
	}
	arr[indexA], arr[indexB] = arr[indexB], arr[indexA]
}

func (m *MaxSlidingWindowByPQ) comp(a, b interface{}) bool {
	va, oka := a.([]int)
	vb, okb := b.([]int)
	if !oka || !okb {
		return false
	}
	return va[0] > vb[0]
}

func (m *MaxSlidingWindowByPQ) GetAttribute() *C.Attribute {
	return &C.Attribute{
		Tags: []string{C.SlidingWindow},
		Desc: &C.Desc{
			Name:        "MaxSlidingWindowByPQ",
			NameCn:      "滑动窗口的最大值",
			Description: "给定一个数组 nums 和滑动窗口的大小 k，请找出所有滑动窗口里的最大值",
			ParamsDesc: map[string]string{
			},
			Example: map[int]string{
				1: "输入: [1,3,-1,-3,5,3,6,7], 和 k = 3,输出: [3,3, 5, 5,6,7]",
			},
		},
	}
}
